#ifndef HAIKUOS_INCLUDE_POSIX_ARCH_X86_64_FPU_H
#define HAIKUOS_INCLUDE_POSIX_ARCH_X86_64_FPU_H

/// floating point data structures and constants

#define __aligned(x) __attribute__((__alighed__(x)))

// environment information of floating point unit
struct env87
{
    int32_t en_cw;      // control word 16 bit
    int32_t en_sw;      // status word
    int32_t en_tw;      // tag word
    int32_t en_flp;     // fp instruction pointer
    uint16_t en_fcs;    // fp code segment selector
    uint16_t en_opcode; // opcode last executed
    int32_t en_foo;     // fp operand offset;
    int32_t en_fos;     // fp operand segment selector
};
// contens of each x87 floating point accumulator
struct fpacc87
{
    uint8_t fp_bytes[10];
};
// flaoting point context x86
struct save87
{
    struct env87 sv_env; // floating point control or status
    // TODO:
};
// contents of each SSE externed accumlator
struct xmmacc
{
    uint8_t xmm_bytes[16];
};
// contents of the upper 16 bytes of each AUX entended accumulator
struct ymmacc
{
    uint8_t ymm_bytes[16];
};

// enamme structs belows depending on machine architecture
#ifdef __i386__
#define __envxmm32 envxmm
#else
#define __envxmm32 envxmm32
#define __envxmm64 envxmm
#endif

// TODO: struct __envxmm 32 64

#undef __envxmm32
#undef __envxmm64

// the hardware default control word for i387's and later coprocessor is
// 0x37F, giving:
// round to nearest
// 64bit precision
// all exceptions masked

// freebsd/i386 uses  53 bit precision for thins like fadd/fsub/fsqrt etc
// because of the difference between memory and fpu register stack arguments
// if its using an itermedidate fpu register, it has 80/64 bits to work
// with. If it uses memory, it has 64/53 bits to work with. However,
// gcc is aware of this and goes to a fair bit of trouble to make the
// best use of it.

// this is mostly academic for amd64, because the API prefers the use
// SSE2 based math. For freebsd/amd64, we go with the default settings.
#define __INITIAL_FPUCW__ 0x037F

#endif // header file protect